package com.djk.service.impl;

import com.djk.constants.SessionKeys;
import com.djk.enums.ResultCode;
import com.djk.mapper.LovemusicMapper;
import com.djk.pojo.Music;
import com.djk.pojo.User;
import com.djk.service.MusicService;
import com.djk.mapper.MusicMapper;
import com.djk.utils.DateFormatUtil;
import com.djk.utils.IdUtil;
import com.djk.utils.MusicTypeValidator;
import com.djk.utils.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author 联想
 * @description 针对表【music】的数据库操作Service实现
 * @createDate
 */
@Service
@Slf4j
public class MusicServiceImpl implements MusicService {
    @Autowired
    private MusicMapper musicMapper;
    @Autowired
    private MusicTypeValidator validator;
    @Value("${music.savePath}")
    private String savePath;    //存储目录
    @Autowired
    private LovemusicMapper lovemusicMapper;

    /**
     * 1.检验是否登录
     * 2.检验文件格式是否为MP3
     * 3.构建存储路径
     * 4.上传文件
     */
    @Override
    @Transactional
    public Result upload(String singer, MultipartFile file, HttpServletRequest request) throws IOException {
        HttpSession session = request.getSession();
        //参数校验
        if (!StringUtils.hasLength(singer) || file == null || file.isEmpty()) {
            return Result.baseResult(ResultCode.REQUEST_PARAMETER_ERROR);
        }

        String originalFilename = file.getOriginalFilename();//源文件名 xxx.mp3
        //获取文件后缀.xxx
        String fileSuffix = originalFilename.substring(originalFilename.lastIndexOf("."));
        //判断这个文件是否合法
        //不合法直接返回
        try (InputStream is = file.getInputStream()) {
            if (!validator.isSupportFileSuffix(fileSuffix.substring(1)) || !validator.isSupportMimeType(is)) {
                return Result.audioTypeError();
            }
        }
        //文件合法，存储
        String path = savePath + originalFilename; //文件存储完整路径
        //如果path下已经存在该文件，则直接返回
        File dest = new File(path);
        //构造music对象，保存到数据库
        String title = originalFilename.substring(0, originalFilename.lastIndexOf("."));
        String url = "/music/getMusic?path=" + originalFilename;
        //从session中拿到用户信息
        User user = (User) session.getAttribute(SessionKeys.USER_INFO_SESSION);
        Music music = new Music();
        music.setUserid(user.getId());
        music.setSinger(singer);
        music.setTitle(title);
        music.setUrl(url);
        music.setTime(DateFormatUtil.dateFormate(new Date()));
        music.setType(fileSuffix);
        //先查询数据库是否有重复记录，有重复数据就只更新
        try {
            Integer rows = musicMapper.queryByUserIdTitleAndType(music);
            if (rows != null && rows > 0) {
                int ret = musicMapper.updateMusic(music);
                return Result.ok();
            }
//            if (rows != null && rows > 0) {
//                musicMapper.deleteByUserIdTitleAndType(music);
//            }
            //插入数据库
            musicMapper.insertOne(music);
            //存储物理文件
            if (!dest.exists()){
                file.transferTo(dest);
            }
            return Result.ok();
        } catch (Exception e) {
            //发生异常，删除
//            dest.delete();
            return Result.error("服务端文件删除异常！");
        }
    }

    /**
     * 获取文件内容
     *
     * @return
     */
    /*@Override
    public ResponseEntity<byte[]> getMusic(String musicAllName){
        String path = savePath + musicAllName;
        //指定音乐的全路径
        File file = new File(path);
        byte[] bytes = new byte[0];
        try {
            bytes = Files.readAllBytes(file.toPath());
        } catch (IOException e) {
            e.printStackTrace();
            //发生异常，说明文件名错误，读取不到内容
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        }
        return new ResponseEntity<>(bytes, HttpStatus.OK);
    }*/
    @Override
    public Result getMusic(String musicAllName) {
        if (!StringUtils.hasLength(musicAllName)) {
            return Result.error("请求参数错误！");
        }
        String path = savePath + musicAllName;
        //指定音乐的全路径
        File file = new File(path);
        byte[] bytes = new byte[0];
        try {
            Path p = file.toPath();
            bytes = Files.readAllBytes(p);
        } catch (IOException e) {
            e.printStackTrace();
            //发生异常，说明文件名错误，读取不到内容
            return Result.error("请求参数错误");
        }
        return Result.ok(bytes);
    }

    /**
     * 根据id删除music
     */
    @Override
    @Transactional
    public Result deleteMusicById(Integer musicId, HttpSession session) {
        if (musicId == null || musicId < 0) {
            return Result.error("请求参数错误！");
        }
        Music music = musicMapper.queryById(musicId);
        if (music == null) {
            return Result.error("没有你要删除的音乐！");
        }
        //删除数据库中的记录
        Integer rows = musicMapper.deleteById(musicId);
        //删除本地对应的资源
//        String path = savePath + music.getTitle() + music.getType();
//        File file = new File(path);
//        if (!file.delete()) {
//            log.info("{}服务器文件删除失败！", file);
//            Result.error("服务器文件删除失败");
//        }

        //lovemusic中的记录同步删除
        User user = (User) session.getAttribute(SessionKeys.USER_INFO_SESSION);
        Integer userId = user.getId();
        rows = lovemusicMapper.deleteLovemusic(userId, musicId);
        return Result.ok();
    }

    @Override
    public Result findMusicById(Integer id) {
        if (id == null || id < 0) {
            return Result.error("请求参数错误！");
        }
        Music music = musicMapper.queryById(id);
        return Result.ok();
    }

    @Override
    @Transactional
    public Result deleteSelect(List<Integer> ids, HttpSession session) {
        //参数校验
        if (ids == null) {
            return Result.error("请求参数错误！");
        }
        User user = (User) session.getAttribute(SessionKeys.USER_INFO_SESSION);
        Integer userId = user.getId();
        int rows = musicMapper.deleteByIds(ids);
        /**
         * 删除音乐后，收藏的音乐同步删除
         */
        lovemusicMapper.deleteByMusicIds(userId, ids);
        return Result.ok();
    }

    @Override
    public Result findMusic(String musicName) {
        List<Music> musicList = new ArrayList<>();
        //如果未传参，直接返回所有记录
        if (musicName == null) {
            musicList = musicMapper.queryAll(IdUtil.getId());
        } else {
            //传入参数，就正常查询
            musicList = musicMapper.queryByName(musicName, IdUtil.getId());
        }

        return Result.ok(musicList);
    }
}




